/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package replic;

import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;
import replic.catalog.Catalog;
import replic.catalog.DB;
import replic.commons.OutputMessage;
import replic.sla.DBService;
import replic.sla.SLA;

/**
 *
 * @author Leonardo Oliveira Moreira
 */
public class RepliCService extends Thread {

    private ServerSocket serverSocket = null;
    private Catalog catalog;
    private int replicPort;
    private List<DBService> dbServiceList = null;

    public RepliCService(int replicPort, Catalog catalog, List<DBService> dbServiceList) {
        this.replicPort = replicPort;
        this.catalog = catalog;
        this.dbServiceList = dbServiceList;
        OutputMessage.println("RepliC Service is starting");
        try {
            serverSocket = new ServerSocket(replicPort);
        } catch (IOException ex) {
            OutputMessage.println(ex.getMessage());
            serverSocket = null;
        }
        List<DB> databaseList = catalog.getDatabaseList();
        OutputMessage.println("Testing databases connection");
        for (DB db : databaseList) {
            DatabaseProxy databaseProxy = new DatabaseProxy(db.getDbDriver(), db.getDbUrl(), db.getDbName(), db.getDbUser(), db.getDbPassword(), db.getVmName());
            if (databaseProxy.isActive()) {
                OutputMessage.println(db.toString() + " is connected");
            } else {
                OutputMessage.println(db.toString() + " is not connected");
                System.exit(0);
            }
            databaseProxy.close();
        }
    }

    @Override
    public void run() {
        OutputMessage.println("RepliC Service is running");
        while (serverSocket != null && !serverSocket.isClosed()) {
            try {
                Socket dbConnection = serverSocket.accept();

                OutputMessage.println("Receiving a connection request from " + dbConnection.toString());

                ClientProxy clientProxy = new ClientProxy(this, dbConnection, catalog);
                clientProxy.start();
            } catch (IOException ex) {
                OutputMessage.println(ex.getMessage());
            }
        }
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        OutputMessage.println("### RepliC Console v.0.1");
        if (args == null || args.length != 4) {
            OutputMessage.println("Command Sintax......: java -jar replic.jar <catalog XML file> <SLA XML file> <replic_db_port> <replic_agent_listener_port>");
            OutputMessage.println("Command Example.....: java -jar replic.jar /home/user/catalog.xml /home/user/sla.xml 7777 7778");
        } else {
            String catalogParam = args[0];
            String slaParam = args[1];
            String replicDbPortParam = args[2];
            String replicAgentPortParam = args[3];

            File c = new File(catalogParam);
            if (!c.exists()) {
                OutputMessage.println("ERROR: " + catalogParam + " not exists");
                System.exit(0);
            }
            c = new File(slaParam);
            if (!c.exists()) {
                OutputMessage.println("ERROR: " + slaParam + " not exists");
                System.exit(0);
            }

            int replicDbPort = -1;
            try {
                replicDbPort = Integer.parseInt(replicDbPortParam);
            } catch (Exception ex) {
                OutputMessage.println("ERROR: " + replicDbPortParam + " is not a port valid");
                System.exit(0);
            }
            
            int replicAgentPort = -1;
            try {
                replicAgentPort = Integer.parseInt(replicAgentPortParam);
            } catch (Exception ex) {
                OutputMessage.println("ERROR: " + replicAgentPortParam + " is not a port valid");
                System.exit(0);
            }

            Catalog catalog = null;
            try {
                catalog = new Catalog(c);
            } catch (IOException ex) {
                OutputMessage.println("ERROR: " + ex.getMessage());
                System.exit(0);
            }
            List<DBService> dbServiceList = null;
            try {
                dbServiceList = SLA.getVirtualMachineList(slaParam);
            } catch (IOException ex) {
                OutputMessage.println("ERROR: " + ex.getMessage());
                System.exit(0);
            }
            RepliCService repliCService = new RepliCService(replicDbPort, catalog, dbServiceList);
            repliCService.start();
            RepliCAgentListener repliCAgentListener = new RepliCAgentListener(replicAgentPort);
            repliCAgentListener.start();
        }
    }
}